#pragma once
#include "vn/Stream.h"

void stub_StreamTest_can(const Stream &x, bool r, bool w, bool s) {

//	assert(x.CanRead()	== r);
//	assert(x.CanWrite()	== w);
//	assert(x.CanSeek()	== s);
}

void stub_StreamTest_seek(Stream &x) {
	StmLen len = x.GetLength();

	x.SetPosition(0);
	assert( x.GetPosition()				== 0);

	x.SetPosition(len + 1);
	assert( x.GetPosition()				== len + 1);

	assert( x.Seek(0, SeekBegin)		== 0);
	assert( x.GetPosition()				== 0);

	assert( x.Seek(UINT_MAX, SeekBegin)	== UINT_MAX );
	assert( x.GetPosition()				== UINT_MAX);

	assert( x.Seek(len, SeekBegin)		== len );
	assert( x.GetPosition()				== len);

	assert( x.Seek(len + 1, SeekBegin)	== len + 1 );
	assert( x.GetPosition()				== len + 1 );


	x.Seek(0, SeekBegin);
	if(len >= 5) {
		assert(x.Seek(2, SeekCurrent)	== 2);
		assert(x.GetPosition()			== 2);
		assert(x.Seek(len, SeekCurrent)	== len + 2);
		assert(x.GetPosition()			== len + 2);
		assert(x.Seek(-len, SeekCurrent)== 2);
		assert(x.GetPosition()			== 2);

		assert(x.Seek(+2, SeekEnd)		== len + 2);
		assert(x.GetPosition()			== len + 2);
		assert(x.Seek(-2, SeekEnd)		== len - 2);
		assert(x.GetPosition()			== len - 2);
	}

	REQUIRE_EXCEPTION( x.Seek(-1,				SeekBegin) );
// FileStream	REQUIRE_EXCEPTION( x.Seek(UINT_MAX + 1LL,	SeekBegin) );

	REQUIRE_EXCEPTION( x.Seek(-len-1,				SeekCurrent) );
// FileStream	REQUIRE_EXCEPTION( x.Seek(UINT_MAX + 1LL,	SeekCurrent) );

	REQUIRE_EXCEPTION( x.Seek(-len-1,				SeekEnd) );
// FileStream	REQUIRE_EXCEPTION( x.Seek(UINT_MAX + 1LL,	SeekEnd) );
}

void stub_StreamTest_read_write(Stream &x) {
	Buf8 buf[15];

	x.SetPosition(3);
	x.SetLength(0);
	assert(x.GetLength()	== 0);
	assert(x.GetPosition()	== 3);
	assert(x.Read(buf, 5)	== 0);

	x.Seek(0, SeekBegin);
	x.Write("12345", 5);
	assert(x.GetLength()	== 5);
	assert(x.GetPosition()	== 5);
	assert(x.Read(buf, 10)	== 0);

	x.Write("12345", 5);
	assert(x.GetLength()	== 10);
	assert(x.GetPosition()	== 10);
	assert(x.Read(buf, 10)	== 0);

	x.Seek(-5, SeekEnd);
	x.Write("67890", 5);
	assert(x.GetLength()	== 10);
	assert(x.GetPosition()	== 10);
	assert(x.Read(buf, 10)	== 0);

	x.Seek(0, SeekBegin);
	assert(x.Read(buf, 5)	== 5);
	assert(x.GetLength()	== 10);
	assert(x.GetPosition()	== 5);
	assert(memcmp(buf, "12345", 5) == 0);

	assert(x.Read(buf, 10)	== 5);
	assert(x.GetLength()	== 10);
	assert(x.GetPosition()	== 10);
	assert(memcmp(buf, "67890", 5) == 0);

	x.Seek(0, SeekBegin);
	assert(x.Read(buf, 15)	== 10);
	assert(x.GetLength()	== 10);
	assert(x.GetPosition()	== 10);
	assert(memcmp(buf, "1234567890", 10) == 0);

	x.Seek(+2, SeekEnd);
	x.Write("ab", 2);

	x.Seek(0, SeekBegin);
	assert(x.Read(buf, 15)	== 14);
	assert(x.GetLength()	== 14);
	assert(x.GetPosition()	== 14);
	assert(memcmp(buf, "1234567890\0\0ab", 14) == 0);
}

void stub_StreamTest_exception_if_close(Stream &x) {

	// how to check if x is close?

	Buf8 buf[10];
	REQUIRE_EXCEPTION(x.Read(buf, 10));
	REQUIRE_EXCEPTION(x.Write(buf, 10));

	REQUIRE_EXCEPTION(x.Seek(0, SeekBegin));

	REQUIRE_EXCEPTION(x.GetPosition());
	REQUIRE_EXCEPTION(x.SetPosition(0));

	REQUIRE_EXCEPTION(x.GetLength());
	REQUIRE_EXCEPTION(x.SetLength(0));
	REQUIRE_EXCEPTION(x.Flush());
}
